using System.Collections.Generic;

namespace Arcane.Source.Utils;

public interface IDeferedEvent<C>
{
    void Process(C ctx);
}

public class EventStorage<C, E> where E : IDeferedEvent<C>
{
    private readonly Queue<EventInstance> eventQueue = [];

    public void Push(E e, int? deferTicks = null)
    {
        eventQueue.Enqueue(new(e, deferTicks));
    }

    public void ProcessAll(C ctx)
    {
        while (eventQueue.Count > 0)
        {
            var inst = eventQueue.Dequeue();
            if (inst.ticks > 0)
            {
                inst.ticks -= 1;
                eventQueue.Enqueue(inst);
            }
            else
            {
                inst.Process(ctx);
            }
        }
    }

    private struct EventInstance(E e, int? ticks)
    {
        public int? ticks = ticks;
        public E e = e;

        public void Process(C ctx) => e.Process(ctx);
    }
}